package com.xingfly.authentication;

import com.xingfly.authentication.annotation.Authorization;
import com.xingfly.constant.ErrorConstant;
import com.xingfly.constant.HttpConstant;
import com.xingfly.constant.HttpStatus;
import com.xingfly.error.TipException;
import com.xingfly.model.TokenModel;
import com.xingfly.service.RedisTokenManager;
import com.xingfly.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;

/**
 * Created by SuperS on 19/05/2017.
 * 拦截器-权限验证
 *
 * @author SuperS
 */
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private RedisTokenManager redisTokenManager;
    @Autowired
    private RoleService roleService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //如果没有注解验证直接通过
        if (method.getAnnotation(Authorization.class) == null) {
            return true;
        }
        String authorization = request.getHeader(HttpConstant.AUTHORIZATION);
        TokenModel model = redisTokenManager.getToken(authorization);


        if (redisTokenManager.checkToken(model, request.getSession().getId())) {
            //获取所需要的权限
            String roleName = method.getAnnotation(Authorization.class).role();
            //查找当前用户的权限
            List<String> roleNameList = roleService.findRolesNameByUserId(model.getId());
            //判断是否拥有该权限
            if (roleNameList.contains(roleName)) {
                // 如果 token 验证成功，将 token 对应的用户 id 存在 request 中，便于之后注入
                request.setAttribute(HttpConstant.CURRENT_USER_ID, model.getId());
                return true;
            }
            throw new TipException(HttpStatus.STATUS_INFO_FORBIDDEN, HttpStatus.STATUS_CODE_FORBIDDEN);
        }

        if (method.getAnnotation(Authorization.class) != null) {
            throw new TipException(ErrorConstant.ERROR_MSG_TOKEN_ERROR, ErrorConstant.ERROR_CODE_TOKEN_ERROR);
        }


        return super.preHandle(request, response, handler);
    }
}
